package jp.gr.java_conf.ryz.summarize.android.logic;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import jp.gr.java_conf.ryz.summarize.android.model.Board;
import jp.gr.java_conf.ryz.summarize.android.model.Category;
import jp.gr.java_conf.ryz.summarize.android.model.Post;
import jp.gr.java_conf.ryz.summarize.android.model.Thred;

import org.apache.commons.lang3.StringUtils;

import android.util.Log;

public class DataCreator
{
	private static final String DAT_SEPARATOR = "<>";
	private static final String REGEXP_ANCHOR_TAG = "</?a.*?>";
	private static final String CHARSET = "Shift-JIS";
	private static final int BODY_NUMBER = 1;
	
	public static List<Category> getCategories()
	{	
		return getCategoriesInternal();
	}
	
	public static List<Board> getBoards(Category category)
	{
		return getBoardsInternal(category);
	}
	
	public static List<Thred> getThreads(Board board)
	{
		return getThreadsInternal(board);
	}
	
	public static List<Post> getPosts(Thred thread)
	{	
		List<Post> posts = getPostsInternal(thread);
		
		return posts;
	}
	
	
	private static List<Category> getCategoriesInternal()
	{
		List<Category> categories = new ArrayList<Category>();
		
		try
		{
			URL url = new URL("http://menu.2ch.net/bbsmenu.html");
			HttpURLConnection connection = (HttpURLConnection)url.openConnection();
			connection.setRequestMethod("GET");
			connection.connect();
			
//			_logger.info("ResponseCode=[" + connection.getResponseCode() + "]");
			
			if (connection.getResponseCode() == 200)
			{
				BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), CHARSET));
				Category currentCategory = null;
				while (true)
				{
					String line = reader.readLine();
					if (line == null)
						break;
					
					if (isCategoryLine(line))
					{
						currentCategory = createCategory(line);
						categories.add(currentCategory);
					}
					
					if (isBoardLine(line))
					{
						if (currentCategory != null)
						{
							currentCategory.addBoard(createBoard(line));
						}
					}
				}
				
				StringBuilder sb = new StringBuilder();
				for (Category category : categories)
				{
					sb.append(category.toString());
				}
				
//				_logger.info(sb.toString());
			}
		}
		catch (IOException e)
		{
//			_logger.warning(e.toString());
		}
		
		return categories;
	}
	
	private static boolean isCategoryLine(String line)
	{
		// MEMO : Sample
		//      : <BR><BR><B>hoge</B><BR>
		String regexp = "^<BR><BR><B>.*</B><BR>.*";
		return line.matches(regexp);
	}
	
	private static Category createCategory(String line)
	{
		Category category = new Category();
		category.setName(getCategoryName(line));
		
		return category;
	}
	
	private static String getCategoryName(String line)
	{
		return line.substring("<BR><BR><B>".length(), line.indexOf("</B><BR>"));
	}
	
	private static boolean isBoardLine(String line)
	{
		// MEMO : Sample
		//      : <A HREF=http://headline.2ch.net/bbynews/>����headline</A><br>
		//      : <A HREF=http://www.monazilla.org/ TARGET=_blank>2ch�c�[��</A><br>
		String regexp = "^<A HREF=.*</A><br>";
		return line.matches(regexp);
	}
	
	private static Board createBoard(String line)
	{
		Board board = new Board();
		board.setName(getBoardName(line));
		board.setUrl(getBoardUrl(line));
		
		return board;
	}
	
	private static String getBoardName(String line)
	{
		line = line.substring(line.indexOf(">") + 1, line.length());
		return line.substring(0, line.indexOf("</A><br>"));
	}
	
	private static String getBoardUrl(String line)
	{
		line = line.replaceFirst("<A HREF=", StringUtils.EMPTY);
		int index = line.indexOf(" TARGET=_blank");
		return index < 0
				? line.substring(0, line.indexOf(">"))
				: line.substring(0, index);
	}
	
	private static List<Board> getBoardsInternal(Category category)
	{
		return category.getBoards();
	}
	
	private static List<Thred> getThreadsInternal(Board board)
	{
		List<Thred> result = new ArrayList<Thred>();
		
		try
		{
			String boardUrl = board.getUrl();
			URL url = new URL(boardUrl + "subject.txt");
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			
			int responseCode = conn.getResponseCode();
			
//			_logger.info("ResponseCode=[" + responseCode + "]");
			
			if (responseCode == 200)
			{
				BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), CHARSET));
				while (true)
				{
					String line = reader.readLine();
					if (line == null)
						break;
					
					Thred thred = createThred(boardUrl, line);
					result.add(thred);
				}
			}
		}
		catch (IOException e)
		{
//			_logger.warning(e.toString());
		}
		
		return result;
	}
	
	private static Thred createThred(String boardUrl, String line)
	{
		Thred result = new Thred();
		
		String[] lines = line.split(DAT_SEPARATOR, -1);
		result.setDatUrl(boardUrl + "/dat/" + lines[0]);
		result.setName(lines[1]);
		
		return result;
	}
	
	private static List<Post> getPostsInternal(Thred thread)
	{	
		List<Post> result = new ArrayList<Post>();
		
		BufferedReader br = null;
		InputStreamReader isr = null;
		try
		{
			URL url = new URL(thread.getDatUrl());
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			
			int responseCode = conn.getResponseCode();
			
//			_logger.info("ResponseCode=[" + responseCode + "]");
			
			if (responseCode == 200)
			{
				isr = new InputStreamReader(conn.getInputStream(), CHARSET);
				br = new BufferedReader(isr);
				int number = 1;
				while (true)
				{
					String line = br.readLine();
					if (line == null)
						break;
					
					result.add(createPost(number++, line));
				}
			}
		}
		catch (IOException e)
		{
			Log.e(DataCreator.class.getSimpleName(), e.toString());
		}
		finally
		{
			if (br != null) try { br.close(); } catch (IOException e) { }
			if (isr != null) try { isr.close(); } catch (IOException e) { }
		}
		
		return result;
	}
	
	private static Post createPost(int number, String line)
	{
		Post result = new Post();
		
		result.setNumber(number);
		String[] splitedLine = line.split(DAT_SEPARATOR, -1);
		result.setName(getPostName(splitedLine));
		result.setDate(getPostDate(splitedLine));
		result.setMail(getPostMail(splitedLine));
		result.setBody(getPostBody(splitedLine));
		
		if (number == BODY_NUMBER)
		{
			result.setIsMain(true);
		}
		
		return result;
	}
	
	private static String getPostName(String[] splitedLine)
	{
		return splitedLine[0];
	}
	
	private static String getPostMail(String[] splitedLine)
	{
		return splitedLine[1];
	}
	
	private static String getPostDate(String[] splitedLine)
	{
		return splitedLine[2];
	}
	
	private static String getPostBody(String[] splitedLine)
	{
		// remove anchor tag.
		return splitedLine[3].replaceAll(REGEXP_ANCHOR_TAG, StringUtils.EMPTY);
	}
}
